<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>

	<body>
		<script type="text/javascript">
			//地图类
			(function() {
				//地图构造函数
				//参数  宽  高  背景色
				function MapG(width, height, bgColor) {
					this.width = width;
					this.height = height;
					this.bgColor = bgColor;

				}
				//创建dom元素,添加到body上
				//将创建的方法添加到原型对象上,共享资源,节省空间
				MapG.prototype.init = function() {
					//1.创建地图div
					var divMap = document.createElement('div');
					//2.设置div属性
					divMap.style.width = this.width + 'px';
					divMap.style.height = this.height + 'px';
					divMap.style.background = this.bgColor;
					divMap.style.position = 'relative';
					divMap.id = 'divMap';
					//3.添加到body
					document.body.appendChild(divMap);
				}
				//把MapG公布到外面
				window.MapG = MapG;
			}());

			//食物类
			(function() {
				//食物数组
				var elements = [];
				//食物的构造函数
				// 参数 宽  高  背景色
				function Food(width, height, bgColor) {
					this.width = width;
					this.height = height;
					this.bgColor = bgColor;
					//食物在地图中的x坐标的格数
					this.x = 0;
					//食物在地图中的y坐标的格数
					this.y = 0;
				}
				//创建dom元素,添加到body上
				//将创建的方法添加到原型对象上,共享资源,节省空间
				Food.prototype.init = function() {
					remove();
					//1.创建div元素
					var divFood = document.createElement('div');
					//2.设置div属性
					divFood.style.width = this.width + 'px';
					divFood.style.height = this.height + 'px';
					divFood.style.background = this.bgColor;
					divFood.style.position = 'absolute';
					var divMap = document.getElementById('divMap');
					//用地图的宽度除以食物的宽度得到的是格数(800/20) = 40(格数)
					//生成一个0-40的随机数,最大的格数39,向下取整,
					//得到一个0-39的随机整数
					this.x = parseInt(Math.random() * (divMap.offsetWidth / this.width));
					this.y = parseInt(Math.random() * (divMap.offsetHeight / this.height));
					//格数*宽度 = 像素值
					divFood.style.left = this.x * this.width + 'px';
					divFood.style.top = this.y * this.height + 'px';
					//3.添加到map中
					divMap.appendChild(divFood);
					//4
					elements.push(divFood);
				}
				//删除食物
				function remove() {
					for(var i = 0; i < elements.length; i++) {
						//从dom中删除
						elements[i].parentElement.removeChild(elements[i]);
						//清空数组
						elements.splice(i, 1);
					}
				}
				//把Food公布到外面
				window.Food = Food;
			}());

			//蛇🐍类
			(function() {
				//存储蛇身的三个div
				var elements = [];
				//蛇的构造函数
				//参数  宽  高    蛇的方向
				function Snake(width, height, dir) {
					//初始化蛇的属性
					this.width = width;
					this.height = height;
					this.dir = dir;
					//蛇的身体,默认三部分,蛇头,蛇身,蛇尾
					this.snBody = [{
						x: 3,
						y: 2,
						bgColor: 'red'
					}, {
						x: 2,
						y: 2,
						bgColor: 'orange'
					}, {
						x: 1,
						y: 2,
						bgColor: 'orange'
					}];
				}
				Snake.prototype.init = function() {
					//在创建新蛇之前,先删除老蛇
					remove();
					//由于蛇默认是三断,创建三个div
					for(var i = 0; i < this.snBody.length; i++) {
						//创建div
						var divBody = document.createElement('div');
						//设置div属性
						divBody.style.width = this.width + 'px';
						divBody.style.height = this.height + 'px';
						//通过遍历依次获取数组中每个元素(对象)中的bgColor属性
						divBody.style.background = this.snBody[i].bgColor;
						divBody.style.position = 'absolute';
						divBody.style.left = (this.snBody[i].x * this.width) + 'px';
						divBody.style.top = (this.snBody[i].y * this.height) + 'px';
						//添加到map中
						//从dom中获取map元素
						var divMap = document.getElementById('divMap');
						//将创建好的每个蛇部分添加到地图上
						divMap.appendChild(divBody);
						//把每个div都插入到数组中
						elements.push(divBody);
					}
					//					console.log(elements);
				}
				Snake.prototype.move = function() {
					//把蛇中的坐标给蛇尾,把蛇头的坐标给蛇中
					for(var i = this.snBody.length - 1; i > 0; i--) {
						// this.snBody[2].x = this.snBody[2-1].x
						this.snBody[i].x = this.snBody[i - 1].x;
						this.snBody[i].y = this.snBody[i - 1].y;
					}
					//设置蛇头

					switch(this.dir) {
						case 'right':
							this.snBody[0].x += 1;
							break;
						case 'left':
							this.snBody[0].x -= 1;
							break;
						case 'top':
							this.snBody[0].y -= 1;
							break;
						case 'bottom':
							this.snBody[0].y += 1;
							break;
						default:
							break;
					}

				}
				//删除方法
				function remove() {
					for(var i = elements.length - 1; i >= 0; i--) {
						//1.从document删除map地图上蛇身
						elements[i].parentElement.removeChild(elements[i]);
						//2.从数组中删除,每次删除自己
						elements.splice(i, 1);
					}
				}

				window.Snake = Snake;
			}());

			// 游戏类
			(function() {
				var gameThis = null;
				var timer = null;
				//游戏构造函数
				function Game() {
					//实例化map对象
					this.mapG = new MapG(800, 600, '#ccc');

					//实例化food对象
					this.food = new Food(20, 20, 'green');

					//实例化蛇对象
					this.snake = new Snake(20, 20, 'right');
				}
				Game.prototype.init = function() {
					//对象调用原型中的init方法
					this.mapG.init();
					//调用init初始化函数
					this.food.init();
					//
					this.snake.init();
				}
				Game.prototype.guize = function() {
					gameThis = this;
					timer = window.setInterval(function() {
						//调用init初始化函数
						gameThis.snake.init();
						//调用移动方法: 把三截的坐标值重新设置
						gameThis.snake.move();

						//蛇头撞墙死
						if(gameThis.snake.snBody[0].x < -1 || gameThis.snake.snBody[0].x > (gameThis.mapG.width / gameThis.snake.width) || gameThis.snake.snBody[0].y < -1 || gameThis.snake.snBody[0].y > (gameThis.mapG.height / gameThis.snake.height)) {
							//停止定时器
							clearInterval(timer);
						}

						//吃食物长尾巴
						//						当食物的x和y坐标和食物的xy坐标完全相等的时候,涨尾巴,生成新食物
						if(gameThis.snake.snBody[0].x == gameThis.food.x && gameThis.snake.snBody[0].y == gameThis.food.y) {
							//1.生成新食物
							gameThis.food.init();
							//2.长尾巴
							var obj = {
								x: gameThis.snake.snBody[gameThis.snake.snBody.length-1].x,
								y: gameThis.snake.snBody[gameThis.snake.snBody.length-1].y,
								bgColor: 'orange'
							};
							//将蛇新增的蛇尾添加到蛇身里
							gameThis.snake.snBody.push(obj);
							
						}
					}, 100);

					//键盘按下事件
					document.onkeydown = function(e) {
						switch(e.keyCode) {
							case 37:
								gameThis.snake.dir = 'left';
								break;
							case 38:
								gameThis.snake.dir = 'top';
								break;
							case 39:
								gameThis.snake.dir = 'right';
								break;
							case 40:
								gameThis.snake.dir = 'bottom';
								break;
							default:
								break;
						}
					}
				}
				window.Game = Game;
			}());

			//			//实例化map对象
			//			var mapG = new MapG(800, 600, '#ccc');
			//
			//			//对象调用原型中的init方法
			//			mapG.init();
			//			//实例化food对象
			//			var food = new Food(20, 20, 'green');
			//			//调用init初始化函数
			//			food.init();
			//			//实例化蛇对象
			//			var snake = new Snake(20, 20, 'right');
			//
			//			setInterval(function() {
			//				//调用init初始化函数
			//				snake.init();
			//				//调用移动方法: 把三截的坐标值重新设置
			//				snake.move();
			//			}, 100);
			//实例化游戏
			var game = new Game();
			game.init();
			game.guize();
		</script>
	</body>

</html>